<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { getAllImages, deleteImage, type ImageData } from '../services/indexedDBStorage'
import { formatFileSize } from '../utils/imageUtils'
import { formatDate, formatFullDateTime } from '../utils/dateUtils'

/**
 * 图片管理组件
 * 提供图片查看、删除等功能
 */

const emit = defineEmits<{
  close: []
}>()

// 组件状态
const images = ref<ImageData[]>([])
const imageUrls = ref<Map<string, string>>(new Map())
const isLoading = ref(true)
const selectedImages = ref<Set<string>>(new Set())
const viewMode = ref<'grid' | 'list'>('grid')
const sortBy = ref<'date' | 'name' | 'size'>('date')
const sortOrder = ref<'asc' | 'desc'>('desc')
const searchKeyword = ref('')

// 预览模态框
const showPreview = ref(false)
const previewImage = ref<ImageData | null>(null)
const previewUrl = ref('')

/**
 * 加载所有图片
 */
const loadImages = async () => {
  isLoading.value = true
  try {
    const allImages = await getAllImages()
    images.value = allImages

    // 创建预览URL
    for (const image of allImages) {
      const url = createImagePreviewUrl(image.data)
      imageUrls.value.set(image.id, url)
    }
  } catch (error) {
    console.error('加载图片失败:', error)
  } finally {
    isLoading.value = false
  }
}

/**
 * 过滤和排序后的图片列表
 */
const filteredImages = computed(() => {
  let filtered = images.value

  // 搜索过滤
  if (searchKeyword.value) {
    const keyword = searchKeyword.value.toLowerCase()
    filtered = filtered.filter((img) => img.name.toLowerCase().includes(keyword))
  }

  // 排序
  filtered.sort((a, b) => {
    let comparison = 0

    switch (sortBy.value) {
      case 'name':
        comparison = a.name.localeCompare(b.name)
        break
      case 'size':
        comparison = a.size - b.size
        break
      case 'date':
      default:
        comparison = new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
        break
    }

    return sortOrder.value === 'asc' ? comparison : -comparison
  })

  return filtered
})

/**
 * 计算总大小
 */
const totalSize = computed(() => {
  return images.value.reduce((total, img) => total + img.size, 0)
})

/**
 * 选择图片
 * @param imageId 图片ID
 */
const toggleImageSelection = (imageId: string) => {
  if (selectedImages.value.has(imageId)) {
    selectedImages.value.delete(imageId)
  } else {
    selectedImages.value.add(imageId)
  }
}

/**
 * 全选/取消全选
 */
const toggleSelectAll = () => {
  if (selectedImages.value.size === filteredImages.value.length) {
    selectedImages.value.clear()
  } else {
    selectedImages.value.clear()
    filteredImages.value.forEach((img) => {
      selectedImages.value.add(img.id)
    })
  }
}

/**
 * 删除选中的图片
 */
const deleteSelectedImages = async () => {
  if (selectedImages.value.size === 0) return

  const count = selectedImages.value.size
  if (!confirm(`确定要删除选中的 ${count} 张图片吗？此操作不可恢复！`)) {
    return
  }

  try {
    const deletePromises = Array.from(selectedImages.value).map(async (imageId) => {
      await deleteImage(imageId)

      // 清理预览URL
      const url = imageUrls.value.get(imageId)
      if (url) {
        revokeImagePreviewUrl(url)
        imageUrls.value.delete(imageId)
      }
    })

    await Promise.all(deletePromises)

    // 从列表中移除已删除的图片
    images.value = images.value.filter((img) => !selectedImages.value.has(img.id))
    selectedImages.value.clear()

    console.log(`成功删除 ${count} 张图片`)
  } catch (error) {
    console.error('删除图片失败:', error)
    alert('删除图片失败，请重试')
  }
}

/**
 * 预览图片
 * @param image 图片数据
 */
const previewImageModal = (image: ImageData) => {
  previewImage.value = image
  previewUrl.value = imageUrls.value.get(image.id) || ''
  showPreview.value = true
}

/**
 * 关闭预览
 */
const closePreview = () => {
  showPreview.value = false
  previewImage.value = null
  previewUrl.value = ''
}

/**
 * 复制图片Markdown语法
 * @param imageId 图片ID
 * @param imageName 图片名称
 */
const copyImageMarkdown = async (imageId: string, imageName: string) => {
  const markdown = `![${imageName}](image://${imageId})`

  try {
    await navigator.clipboard.writeText(markdown)
    alert('Markdown语法已复制到剪贴板')
  } catch (error) {
    console.error('复制失败:', error)
    // 降级方案
    const textArea = document.createElement('textarea')
    textArea.value = markdown
    document.body.appendChild(textArea)
    textArea.select()
    document.execCommand('copy')
    document.body.removeChild(textArea)
    alert('Markdown语法已复制到剪贴板')
  }
}

/**
 * 关闭图片管理器
 */
const closeManager = () => {
  // 清理所有预览URL
  imageUrls.value.forEach((url) => {
    revokeImagePreviewUrl(url)
  })
  imageUrls.value.clear()

  emit('close')
}

// 组件挂载时加载图片
onMounted(() => {
  loadImages()
})
</script>

<template>
  <div class="image-manager-overlay" @click="closeManager">
    <div class="image-manager-panel" @click.stop>
      <!-- 头部 -->
      <div class="manager-header">
        <div class="header-left">
          <h2>图片管理</h2>
          <span class="image-count"
            >{{ images.length }} 张图片，共 {{ formatFileSize(totalSize) }}</span
          >
        </div>
        <button class="close-btn" @click="closeManager">
          <svg viewBox="0 0 24 24" width="20" height="20">
            <path
              fill="currentColor"
              d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
            />
          </svg>
        </button>
      </div>

      <!-- 工具栏 -->
      <div class="manager-toolbar">
        <div class="toolbar-left">
          <div class="search-box">
            <input
              v-model="searchKeyword"
              type="text"
              placeholder="搜索图片..."
              class="search-input"
            />
            <svg class="search-icon" viewBox="0 0 24 24" width="16" height="16">
              <path
                fill="currentColor"
                d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
              />
            </svg>
          </div>

          <select v-model="sortBy" class="sort-select">
            <option value="date">按日期排序</option>
            <option value="name">按名称排序</option>
            <option value="size">按大小排序</option>
          </select>

          <button
            class="sort-order-btn"
            @click="sortOrder = sortOrder === 'asc' ? 'desc' : 'asc'"
            :title="sortOrder === 'asc' ? '升序' : '降序'"
          >
            <svg viewBox="0 0 24 24" width="16" height="16">
              <path
                v-if="sortOrder === 'asc'"
                fill="currentColor"
                d="M3 18h6v-2H3v2zM3 6v2h18V6H3zm0 7h12v-2H3v2z"
              />
              <path v-else fill="currentColor" d="M3 18h18v-2H3v2zM3 6v2h12V6H3zm0 7h6v-2H3v2z" />
            </svg>
          </button>
        </div>

        <div class="toolbar-right">
          <div class="view-toggle">
            <button
              class="view-btn"
              :class="{ active: viewMode === 'grid' }"
              @click="viewMode = 'grid'"
              title="网格视图"
            >
              <svg viewBox="0 0 24 24" width="16" height="16">
                <path
                  fill="currentColor"
                  d="M3 3v8h8V3H3zm6 6H5V5h4v4zm-6 4v8h8v-8H3zm6 6H5v-4h4v4zm4-16v8h8V3h-8zm6 6h-4V5h4v4zm-6 4v8h8v-8h-8zm6 6h-4v-4h4v4z"
                />
              </svg>
            </button>
            <button
              class="view-btn"
              :class="{ active: viewMode === 'list' }"
              @click="viewMode = 'list'"
              title="列表视图"
            >
              <svg viewBox="0 0 24 24" width="16" height="16">
                <path
                  fill="currentColor"
                  d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"
                />
              </svg>
            </button>
          </div>

          <button v-if="selectedImages.size > 0" class="delete-btn" @click="deleteSelectedImages">
            删除选中 ({{ selectedImages.size }})
          </button>
        </div>
      </div>

      <!-- 批量操作 -->
      <div v-if="filteredImages.length > 0" class="batch-actions">
        <label class="select-all">
          <input
            type="checkbox"
            :checked="selectedImages.size === filteredImages.length && filteredImages.length > 0"
            :indeterminate="selectedImages.size > 0 && selectedImages.size < filteredImages.length"
            @change="toggleSelectAll"
          />
          全选
        </label>
      </div>

      <!-- 图片列表 -->
      <div class="manager-content">
        <div v-if="isLoading" class="loading-state">
          <div class="loading-spinner"></div>
          <p>加载图片中...</p>
        </div>

        <div v-else-if="filteredImages.length === 0" class="empty-state">
          <div class="empty-icon">
            <svg viewBox="0 0 24 24" width="48" height="48">
              <path
                fill="currentColor"
                d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"
              />
            </svg>
          </div>
          <h3>{{ searchKeyword ? '未找到匹配的图片' : '暂无图片' }}</h3>
          <p>{{ searchKeyword ? '尝试使用其他关键词搜索' : '开始在笔记中粘贴图片吧' }}</p>
        </div>

        <!-- 网格视图 -->
        <div v-else-if="viewMode === 'grid'" class="image-grid">
          <div
            v-for="image in filteredImages"
            :key="image.id"
            class="image-card"
            :class="{ selected: selectedImages.has(image.id) }"
          >
            <div class="image-checkbox">
              <input
                type="checkbox"
                :checked="selectedImages.has(image.id)"
                @change="toggleImageSelection(image.id)"
              />
            </div>

            <div class="image-preview" @click="previewImageModal(image)">
              <img :src="imageUrls.get(image.id)" :alt="image.name" class="preview-img" />
            </div>

            <div class="image-info">
              <h4 class="image-name" :title="image.name">{{ image.name }}</h4>
              <div class="image-meta">
                <span class="image-size">{{ formatFileSize(image.size) }}</span>
                <span class="image-date">{{ formatDate(new Date(image.createdAt)) }}</span>
              </div>
            </div>

            <div class="image-actions">
              <button
                class="action-btn"
                @click="copyImageMarkdown(image.id, image.name)"
                title="复制Markdown"
              >
                <svg viewBox="0 0 24 24" width="14" height="14">
                  <path
                    fill="currentColor"
                    d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"
                  />
                </svg>
              </button>
            </div>
          </div>
        </div>

        <!-- 列表视图 -->
        <div v-else class="image-list">
          <div
            v-for="image in filteredImages"
            :key="image.id"
            class="image-row"
            :class="{ selected: selectedImages.has(image.id) }"
          >
            <div class="row-checkbox">
              <input
                type="checkbox"
                :checked="selectedImages.has(image.id)"
                @change="toggleImageSelection(image.id)"
              />
            </div>

            <div class="row-preview" @click="previewImageModal(image)">
              <img :src="imageUrls.get(image.id)" :alt="image.name" class="preview-thumb" />
            </div>

            <div class="row-info">
              <h4 class="row-name">{{ image.name }}</h4>
              <div class="row-meta">
                <span>{{ formatFileSize(image.size) }}</span>
                <span>{{ formatFullDateTime(new Date(image.createdAt)) }}</span>
              </div>
            </div>

            <div class="row-actions">
              <button
                class="action-btn"
                @click="copyImageMarkdown(image.id, image.name)"
                title="复制Markdown"
              >
                <svg viewBox="0 0 24 24" width="14" height="14">
                  <path
                    fill="currentColor"
                    d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"
                  />
                </svg>
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 图片预览模态框 -->
    <div v-if="showPreview" class="preview-modal" @click="closePreview">
      <div class="preview-content" @click.stop>
        <div class="preview-header">
          <h3>{{ previewImage?.name }}</h3>
          <button class="close-btn" @click="closePreview">
            <svg viewBox="0 0 24 24" width="20" height="20">
              <path
                fill="currentColor"
                d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
              />
            </svg>
          </button>
        </div>

        <div class="preview-body">
          <img :src="previewUrl" :alt="previewImage?.name" class="preview-image" />
        </div>

        <div class="preview-footer">
          <div class="preview-info">
            <span>{{ formatFileSize(previewImage?.size || 0) }}</span>
            <span>{{
              previewImage ? formatFullDateTime(new Date(previewImage.createdAt)) : ''
            }}</span>
          </div>
          <div class="preview-actions">
            <button
              class="action-btn primary"
              @click="copyImageMarkdown(previewImage?.id || '', previewImage?.name || '')"
            >
              复制Markdown
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.image-manager-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.image-manager-panel {
  background: white;
  border-radius: 12px;
  width: 90%;
  height: 80%;
  max-width: 1200px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}

.manager-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  border-bottom: 1px solid #e9ecef;
}

.header-left h2 {
  margin: 0 0 4px 0;
  font-size: 20px;
  font-weight: 600;
  color: #212529;
}

.image-count {
  font-size: 14px;
  color: #6c757d;
}

.close-btn {
  padding: 8px;
  border: none;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
  color: #6c757d;
  transition: all 0.2s;
}

.close-btn:hover {
  background: #f8f9fa;
  color: #212529;
}

.manager-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 24px;
  border-bottom: 1px solid #e9ecef;
  background: #f8f9fa;
}

.toolbar-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.search-box {
  position: relative;
}

.search-input {
  padding: 8px 12px 8px 36px;
  border: 1px solid #dee2e6;
  border-radius: 6px;
  font-size: 14px;
  outline: none;
  width: 200px;
  transition: border-color 0.2s;
}

.search-input:focus {
  border-color: #007bff;
}

.search-icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: #6c757d;
}

.sort-select {
  padding: 8px 12px;
  border: 1px solid #dee2e6;
  border-radius: 6px;
  font-size: 14px;
  outline: none;
  background: white;
}

.sort-order-btn {
  padding: 8px;
  border: 1px solid #dee2e6;
  border-radius: 6px;
  background: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}

.sort-order-btn:hover {
  background: #f8f9fa;
}

.toolbar-right {
  display: flex;
  align-items: center;
  gap: 12px;
}

.view-toggle {
  display: flex;
  border: 1px solid #dee2e6;
  border-radius: 6px;
  overflow: hidden;
}

.view-btn {
  padding: 8px 12px;
  border: none;
  background: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}

.view-btn:hover {
  background: #f8f9fa;
}

.view-btn.active {
  background: #007bff;
  color: white;
}

.delete-btn {
  padding: 8px 16px;
  border: 1px solid #dc3545;
  border-radius: 6px;
  background: #dc3545;
  color: white;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.2s;
}

.delete-btn:hover {
  background: #c82333;
  border-color: #c82333;
}

.batch-actions {
  padding: 12px 24px;
  border-bottom: 1px solid #e9ecef;
  background: #f8f9fa;
}

.select-all {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: #495057;
  cursor: pointer;
}

.manager-content {
  flex: 1;
  overflow-y: auto;
  padding: 24px;
}

.loading-state,
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 300px;
  color: #6c757d;
}

.loading-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid #f3f3f3;
  border-top: 3px solid #007bff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 16px;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.empty-icon {
  margin-bottom: 16px;
  opacity: 0.5;
}

.empty-state h3 {
  margin: 0 0 8px 0;
  font-size: 18px;
  font-weight: 600;
}

.empty-state p {
  margin: 0;
  font-size: 14px;
}

/* 网格视图 */
.image-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
}

.image-card {
  border: 1px solid #e9ecef;
  border-radius: 8px;
  overflow: hidden;
  transition: all 0.2s;
  position: relative;
}

.image-card:hover {
  border-color: #007bff;
  box-shadow: 0 4px 12px rgba(0, 123, 255, 0.15);
}

.image-card.selected {
  border-color: #007bff;
  background: rgba(0, 123, 255, 0.05);
}

.image-checkbox {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 2;
}

.image-preview {
  height: 150px;
  overflow: hidden;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f8f9fa;
}

.preview-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: cover;
}

.image-info {
  padding: 12px;
}

.image-name {
  margin: 0 0 8px 0;
  font-size: 14px;
  font-weight: 600;
  color: #212529;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.image-meta {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: #6c757d;
}

.image-actions {
  position: absolute;
  top: 8px;
  right: 8px;
  opacity: 0;
  transition: opacity 0.2s;
}

.image-card:hover .image-actions {
  opacity: 1;
}

.action-btn {
  padding: 6px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  background: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}

.action-btn:hover {
  background: #f8f9fa;
}

.action-btn.primary {
  background: #007bff;
  border-color: #007bff;
  color: white;
}

.action-btn.primary:hover {
  background: #0056b3;
  border-color: #0056b3;
}

/* 列表视图 */
.image-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.image-row {
  display: flex;
  align-items: center;
  padding: 12px;
  border: 1px solid #e9ecef;
  border-radius: 8px;
  transition: all 0.2s;
}

.image-row:hover {
  border-color: #007bff;
  background: rgba(0, 123, 255, 0.05);
}

.image-row.selected {
  border-color: #007bff;
  background: rgba(0, 123, 255, 0.05);
}

.row-checkbox {
  margin-right: 12px;
}

.row-preview {
  width: 60px;
  height: 60px;
  margin-right: 16px;
  cursor: pointer;
  border-radius: 6px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f8f9fa;
}

.preview-thumb {
  max-width: 100%;
  max-height: 100%;
  object-fit: cover;
}

.row-info {
  flex: 1;
}

.row-name {
  margin: 0 0 4px 0;
  font-size: 14px;
  font-weight: 600;
  color: #212529;
}

.row-meta {
  display: flex;
  gap: 16px;
  font-size: 12px;
  color: #6c757d;
}

.row-actions {
  margin-left: 16px;
}

/* 预览模态框 */
.preview-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1100;
}

.preview-content {
  background: white;
  border-radius: 12px;
  max-width: 90%;
  max-height: 90%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.preview-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid #e9ecef;
}

.preview-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #212529;
}

.preview-body {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  min-height: 300px;
}

.preview-image {
  max-width: 100%;
  max-height: 100%;
  border-radius: 8px;
}

.preview-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-top: 1px solid #e9ecef;
  background: #f8f9fa;
}

.preview-info {
  display: flex;
  gap: 16px;
  font-size: 14px;
  color: #6c757d;
}

.preview-actions {
  display: flex;
  gap: 8px;
}
</style>
